package fun.tan90.easy.binlog.manager.service.impl;

import cn.hutool.core.date.DateUtil;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import com.wf.captcha.ArithmeticCaptcha;
import fun.tan90.easy.binlog.base.convention.enums.IErrorCode;
import fun.tan90.easy.binlog.base.convention.exception.ClientException;
import fun.tan90.easy.binlog.manager.model.cmd.CaptchaGenerateCmd;
import fun.tan90.easy.binlog.manager.property.EasyBinlogManagerProperties;
import fun.tan90.easy.binlog.manager.service.SysCaptchaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * @author chj
 * @date 2021年08月04日 8:49
 */
@Slf4j
@Service
public class SysCaptchaServiceImpl implements SysCaptchaService {

    @Resource
    EasyBinlogManagerProperties easyBinlogManagerProperties;

    @Override
    public String generateArithmeticCaptcha(CaptchaGenerateCmd captchaGenerateCmd) {
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(captchaGenerateCmd.getWidth(), captchaGenerateCmd.getHeight());
        // 几位数运算，默认是两位
        captcha.setLen(captchaGenerateCmd.getLen());
        // 获取运算的结果：5
        String result = captcha.text();
        log.debug("验证码值为 {}", captcha.getArithmeticString());
        Row row = Db.selectOneBySql("select * from binlog_captcha where captcha_key = ?", captchaGenerateCmd.getCaptchaKey());
        Date now = new Date();
        Date effectiveCutoffTime = DateUtil.offsetMinute(now, captchaGenerateCmd.getSurvival());
        if (Objects.isNull(row)) {
            String insert = "insert into binlog_captcha(captcha_key, captcha_value, effective_cutoff_time, create_time) value (?, ?, ?, ?)";
            Db.insertBySql(insert, captchaGenerateCmd.getCaptchaKey(), result, effectiveCutoffTime, now);
        } else {
            String update = "update binlog_captcha SET captcha_value = ?, effective_cutoff_time = ? where captcha_key = ?";
            Db.updateBySql(update, result, effectiveCutoffTime, captchaGenerateCmd.getCaptchaKey());
        }
        return captcha.toBase64();
    }

    @Override
    public void validate(String captchaKey, String captchaValue) {
        if (!easyBinlogManagerProperties.isValidateCaptcha()) {
            return;
        }
        Row row = Db.selectOneById("binlog_captcha", "captcha_key", captchaKey);
        if (Objects.isNull(row)) {
            throw new ClientException(IErrorCode.AUTH_1001002);
        }
        Date effectiveCutoffTime = row.getDate("effective_cutoff_time");
        if (effectiveCutoffTime.compareTo(new Date()) < 0) {
            throw new ClientException(IErrorCode.AUTH_1001002);
        }
        String captchaRightValue = row.getString("captcha_value");
        try {
            if (!captchaRightValue.equalsIgnoreCase(captchaValue.trim())) {
                throw new ClientException(IErrorCode.AUTH_1001000);
            }
        } finally {
            Db.deleteById("binlog_captcha", "captcha_key", captchaKey);
        }
    }
}
